Give better error messages for invalid manifest-paths
authorCarol (Nichols || Goulding) <carol.nichols@gmail.com>
Sun, 30 Aug 2015 03:17:31 +0000 (23:17 -0400)
committerCarol (Nichols || Goulding) <carol.nichols@gmail.com>
Tue, 1 Sep 2015 01:26:29 +0000 (21:26 -0400)
Inspired by https://github.com/rust-lang/cargo/pull/1182.
Fixes #1158, #1772, #1773.

src/bin/read_manifest.rs
src/bin/verify_project.rs
src/cargo/util/important_paths.rs
tests/test_cargo_read_manifest.rs

index 9c584fa2c3319d9e7b6eb954d195b77c61a75620..2539655f859d62f86f6be683f4e725036920c973 100644 (file)
@@ -1,6 +1,5 @@
 use std::env;
 use std::error::Error;
-use std::path::PathBuf;
 
 use cargo::core::{Package, Source};
 use cargo::util::{CliResult, CliError, Config};
@@ -30,20 +29,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult<Option<Package>>
            env::args().collect::<Vec<_>>());
     try!(config.shell().set_color_config(options.flag_color.as_ref().map(|s| &s[..])));
 
-    // Accept paths to directories containing Cargo.toml for backwards compatibility.
-    let root = match options.flag_manifest_path {
-        Some(path) => {
-            let mut path = PathBuf::from(path);
-            if !path.ends_with("Cargo.toml") {
-                path.push("Cargo.toml");
-            }
-            Some(path.display().to_string())
-        },
-        None => None,
-    };
-    let root = try!(find_root_manifest_for_cwd(root));
-
-    debug!("read-manifest; manifest-path={}", root.display());
+    let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path));
 
     let mut source = try!(PathSource::for_path(root.parent().unwrap(), config).map_err(|e| {
         CliError::new(e.description(), 1)
index 86aa305a6814e8b1340b6359d96b635f1e5aafb8..b1c1b4b613f4b84d99edac75d0a30abb681a020a 100644 (file)
@@ -1,4 +1,5 @@
 use std::collections::HashMap;
+use std::fs;
 use std::fs::File;
 use std::io::prelude::*;
 use std::process;
@@ -36,6 +37,14 @@ pub fn execute(args: Flags, config: &Config) -> CliResult<Option<Error>> {
 
     let mut contents = String::new();
     let filename = args.flag_manifest_path.unwrap_or("Cargo.toml".into());
+
+    if !filename.ends_with("Cargo.toml") {
+        fail("invalid", "the manifest-path must be a path to a Cargo.toml file")
+    }
+    if !fs::metadata(&filename).is_ok() {
+        fail("invalid", &format!("manifest path `{}` does not exist", filename))
+    }
+
     let file = File::open(&filename);
     match file.and_then(|mut f| f.read_to_string(&mut contents)) {
         Ok(_) => {},
index 365ddabe3e383f20d6764c1ffe5df79e69a841fb..1d6076b4b875c8fa923da2ee6a7776bdc79b12f0 100644 (file)
@@ -41,7 +41,16 @@ pub fn find_root_manifest_for_cwd(manifest_path: Option<String>)
         human("Couldn't determine the current working directory")
     }));
     match manifest_path {
-        Some(path) => Ok(cwd.join(&path)),
+        Some(path) => {
+            let absolute_path = cwd.join(&path);
+            if !absolute_path.ends_with("Cargo.toml") {
+                return Err(human("the manifest-path must be a path to a Cargo.toml file"))
+            }
+            if !fs::metadata(&absolute_path).is_ok() {
+                return Err(human(format!("manifest path `{}` does not exist", path)))
+            }
+            Ok(absolute_path)
+        },
         None => find_project_manifest(&cwd, "Cargo.toml"),
     }
 }
index 6f52bb6369b58a07bb2c75e57b026011d74d4746..52f79ccb97839479fd52a32adc5e290507a92c56 100644 (file)
@@ -51,8 +51,8 @@ test!(cargo_read_manifest_path_to_cargo_toml_parent_relative {
     assert_that(p.cargo_process("read-manifest")
                  .arg("--manifest-path").arg("foo")
                  .cwd(p.root().parent().unwrap()),
-                execs().with_status(0)
-                       .with_stdout(read_manifest_output()));
+                execs().with_status(101)
+                       .with_stderr("the manifest-path must be a path to a Cargo.toml file"));
 });
 
 test!(cargo_read_manifest_path_to_cargo_toml_parent_absolute {
@@ -63,8 +63,8 @@ test!(cargo_read_manifest_path_to_cargo_toml_parent_absolute {
     assert_that(p.cargo_process("read-manifest")
                  .arg("--manifest-path").arg(p.root())
                  .cwd(p.root().parent().unwrap()),
-                execs().with_status(0)
-                       .with_stdout(read_manifest_output()));
+                execs().with_status(101)
+                       .with_stderr("the manifest-path must be a path to a Cargo.toml file"));
 });
 
 test!(cargo_read_manifest_cwd {